package top.itaso.lib.common;

import android.content.Context;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Build;
import android.os.Environment;
import android.os.storage.StorageManager;
import android.os.storage.StorageVolume;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

/**
 * @Description: 获取 Android 设备的存储设备
 * @Author dengfu.su
 * @Date 2023/3/6
 */
public class StorageVolumeUtils {
    private static final String TAG = StorageVolumeUtils.class.getSimpleName();

    /**
     * 获取挂载的存储设备，如内部存储、外部存储的 sdcard、U盘等
     * StorageVolume:存储卷、存储磁盘
     *
     * @param context
     */
    public static List<UStorageVolume> getVolumes(Context context) {
        StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);

        ArrayList<UStorageVolume> uStorageVolumes = new ArrayList<>();
        Log.d(TAG, "getVolumes: >>>>>>Build.VERSION.SDK_INT:" + Build.VERSION.SDK_INT);

        try {
            Method getVolumesMethod = StorageManager.class.getDeclaredMethod("getVolumes");
            // getVolumes 的返回结果不会为 null，因为 一旦 null 时会  throw RemoteException.rethrowFromSystemServer()
            List<?> volumeInfos = (List<?>) getVolumesMethod.invoke(storageManager);//其中 ？ 为 android.os.storage.VolumeInfo 类
            Log.d(TAG, "getVolumes: >>>>>>volumeInfos.size=" + volumeInfos.size());

            Class volumeInfoClazz = Class.forName("android.os.storage.VolumeInfo");
            //使用类属性的 get 方法获取信息
            Method getStateMethod = volumeInfoClazz.getDeclaredMethod("getState");
            Method getTypeMethod = volumeInfoClazz.getDeclaredMethod("getType");
            Method getFsUuidMethod = volumeInfoClazz.getDeclaredMethod("getFsUuid");
            Method getFsLabelMethod = volumeInfoClazz.getDeclaredMethod("getDescription");
            Method getPathMethod = volumeInfoClazz.getDeclaredMethod("getPath");
            Method getInternalPathMethod = volumeInfoClazz.getDeclaredMethod("getInternalPath");
            Method getDiskMethod = volumeInfoClazz.getDeclaredMethod("getDisk");
            //使用类属性的 public 属性直接取得
//            Field stateField = volumeInfoClazz.getDeclaredField("state");
//            Field typeField = volumeInfoClazz.getDeclaredField("type");
//            Field fsUuidField = volumeInfoClazz.getDeclaredField("fsUuid");
//            Field fsLabelField = volumeInfoClazz.getDeclaredField("fsLabel");
//            Field pathField = volumeInfoClazz.getDeclaredField("path");
//            Field internalPathField = volumeInfoClazz.getDeclaredField("internalPath");
//            Field diskField = volumeInfoClazz.getDeclaredField("disk");

            Class diskInfoClazz = Class.forName("android.os.storage.DiskInfo");
            Field flagsField = diskInfoClazz.getDeclaredField("flags");
            Method isSdMethod = diskInfoClazz.getDeclaredMethod("isSd");
            Method isUsbMethod = diskInfoClazz.getDeclaredMethod("isUsb");
            Method getDescriptionMethod = diskInfoClazz.getDeclaredMethod("getDescription");

            for (Object volumeInfo : volumeInfos) {
                if (null == volumeInfo) {
                    Log.e(TAG, "getVolumes: >>>>>>volumeInfo is Null");
                    continue;
                }

                int state = (int) getStateMethod.invoke(volumeInfo);
                int type = (int) getTypeMethod.invoke(volumeInfo);
                Object fsUuidObj = getFsUuidMethod.invoke(volumeInfo);
                Object fsLabelObj = getFsLabelMethod.invoke(volumeInfo);
                Object filePathObj = getPathMethod.invoke(volumeInfo);
                Object fileInternalPathObj = getInternalPathMethod.invoke(volumeInfo);
                Object diskInfo = getDiskMethod.invoke(volumeInfo);//内置存储卡为 null
                String fsUuid = (fsUuidObj == null ? "" : (String) fsUuidObj);
                String fsLabel = (fsLabelObj == null ? "" : (String) fsLabelObj);
                String path = (filePathObj == null ? "" : ((File) filePathObj).getPath());
                String internalPath = (fileInternalPathObj == null ? "" : ((File) fileInternalPathObj).getPath());//部分内置存储分区该值为 null

//                int state = (int) stateField.get(volumeInfo);
//                int type = (int) typeField.get(volumeInfo);
//                String fsUuid = (String) fsUuidField.get(volumeInfo);
//                String fsLabel = (String) fsLabelField.get(volumeInfo);
//                String path = (String) pathField.get(volumeInfo);
//                String internalPath = (String) internalPathField.get(volumeInfo);
//                Object disk = diskField.get(volumeInfo);

                //目前发现 非插入存储（如U盘）的存储盘，uuid、fslabel、diskInfo 内容均是空的，internalPath 则可能为空，
                // 反之插入的存储盘中，uuid、fslabel、diskInfo、internalPath 均不为空，
                // 则该方式以这四个属性均有值时判定是外部扩容的存储盘，如 插入 U盘、sd卡

                UStorageVolume uStorageVolume = new UStorageVolume();
                uStorageVolume.setStatus(state);
                uStorageVolume.setType(type);
                uStorageVolume.setFsUuid(fsUuid);
                uStorageVolume.setFsLabel(fsLabel);
                uStorageVolume.setPath(path);
                uStorageVolume.setInternalPath(internalPath);
                uStorageVolume.setRemovable(diskInfo != null && !TextUtils.isEmpty(fsUuid) && !TextUtils.isEmpty(fsLabel) && !TextUtils.isEmpty(internalPath));
                uStorageVolume.setEmulated(!uStorageVolume.isRemovable());
                if (diskInfo != null) {
                    Object label = getDescriptionMethod.invoke(diskInfo);
                    uStorageVolume.setLabel(label == null ? "" : (String) label);
                    uStorageVolume.setSdDisk((Boolean) isSdMethod.invoke(diskInfo));
                    uStorageVolume.setUsbDisk((Boolean) isUsbMethod.invoke(diskInfo));
                    uStorageVolume.setFlags((Integer) flagsField.get(diskInfo));
                } else {
                    uStorageVolume.setLabel("");
                }

                uStorageVolumes.add(uStorageVolume);
                Log.d(TAG, "getVolumes: >>>>>>uStorageVolume=" + uStorageVolume.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return uStorageVolumes;
    }


    /**
     * 获取挂在的存储设备，如内部存储、外部存储的 SDCard、U盘等
     * StorageVolume:存储卷、存储磁盘
     *
     * @param context
     */
//    public static List<UStorageVolume> getStorageVolumes(Context context) {
//        Log.d(TAG, "getStorageVolumes: >>>>>>Build.VERSION.SDK_INT:" + Build.VERSION.SDK_INT);
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//            StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
//
//            ArrayList<UStorageVolume> uStorageVolumes = new ArrayList<>();
//            try {
//                Method getStorageVolumesMethod = StorageManager.class.getDeclaredMethod("getVolumeList");
//                StorageVolume[] storageVolumes = (StorageVolume[]) getStorageVolumesMethod.invoke(storageManager);
//                Log.d(TAG, "getStorageVolumes: >>>>>>storageVolumes.size=" + storageVolumes.length);
//                for (StorageVolume storageVolume : storageVolumes) {
//                    if (null == storageVolume) {
//                        Log.e(TAG, "getStorageVolumes: >>>>>>storageVolume is Null");
//                        continue;
//                    }
//
////                    UStorageVolume uStorageVolume = new UStorageVolume();
////                    uStorageVolume.setStatus(state);
////                    uStorageVolume.setType(type);
////                    uStorageVolume.setFsUuid(fsUuid);
////                    uStorageVolume.setFsLabel(fsLabel);
////                    uStorageVolume.setPath(path);
////                    uStorageVolume.setInternalPath(internalPath);
////                    uStorageVolume.setRemovable(diskInfo != null && !TextUtils.isEmpty(fsUuid) && !TextUtils.isEmpty(fsLabel) && !TextUtils.isEmpty(internalPath));
////                    uStorageVolume.setEmulated(!uStorageVolume.isRemovable());
////                    if (diskInfo != null) {
////                        Object label = getDescriptionMethod.invoke(diskInfo);
////                        uStorageVolume.setLabel(label == null ? "" : (String) label);
////                        uStorageVolume.setSdDisk((Boolean) isSdMethod.invoke(diskInfo));
////                        uStorageVolume.setUsbDisk((Boolean) isUsbMethod.invoke(diskInfo));
////                        uStorageVolume.setFlags((Integer) flagsField.get(diskInfo));
////                    } else {
////                        uStorageVolume.setLabel("");
////                    }
//
//                    //设备挂载的状态，如:mounted、unmounted
//                    String state = storageVolume.getState();
//
//                    //是否是可移除的外部存储设备
//                    boolean isRemovable = storageVolume.isRemovable();
//                    //这个其实就是U盘的名称
//                    String fsLabel = storageVolume.getDescription(context);
//
//                    String uuid = storageVolume.getUuid();
////                        String mediaStoreVolumeName = storageVolume.getMediaStoreVolumeName();
//                    //是否是内部存储设备
//                    boolean isEmulated = storageVolume.isEmulated();
//
//                    UStorageVolume uStorageVolume = new UStorageVolume();
//                    uStorageVolume.setFsUuid(uuid);
//                    uStorageVolume.setLabel(fsLabel);
//                    uStorageVolume.setEmulated(isEmulated);
//                    uStorageVolume.setRemovable(isRemovable);
////                        uStorageVolume.setStatus(status);
//
//                    Method getPathMethod = StorageVolume.class.getDeclaredMethod("getPath");
//                    @SuppressLint("SoonBlockedPrivateApi") Method getInternalPathMethod = StorageVolume.class.getDeclaredMethod("getInternalPath");
//                    //设备的路径
//                    String path = (String) getPathMethod.invoke(storageVolume);
//                    String internalPath = (String) getInternalPathMethod.invoke(storageVolume);
//
//                    uStorageVolume.setPath(path);
//                    uStorageVolume.setInternalPath(internalPath);
//                    Log.d(TAG, "getStorageVolumes: >>>>>>uStorageVolume=" + uStorageVolume.toString());
//                    uStorageVolumes.add(uStorageVolume);
//                }
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//            return uStorageVolumes;
//        }
//
//        return getVolumes(context);
//
//    }

    /**
     * 获取当前应用的私有目录
     *
     * @param context
     * @return
     */
    public static UStorageVolume getPrivateStorageVolume(Context context) {
        String path = context.getFilesDir().getParent();// /data/user/0/top.itaso.app
        UStorageVolume uStorageVolume = new UStorageVolume();
        uStorageVolume.setFsUuid(path);
        uStorageVolume.setLabel(FileUtils.getFileByDir(path).getName());
        uStorageVolume.setFsLabel(uStorageVolume.getLabel());
        uStorageVolume.setPath(path);
        uStorageVolume.setInternalPath(path);
        Log.d(TAG, "getPrivateStorageVolume: >>>>>>content=" + context.toString() + ",uStorageVolume=" + uStorageVolume.toString());
        return uStorageVolume;
    }

    public static String getAppPrivateDir(Context context) {
        StringBuilder privateDirsBuilder = new StringBuilder();
        privateDirsBuilder.append("From Content.getFilesDir:");
        //包含应用程序文件的目录的路径。不需要额外的权限来读取或在返回的路径下写入文件。
        privateDirsBuilder.append("\n--->path:" + context.getFilesDir());// /data/user/0/top.itaso.app/files
        privateDirsBuilder.append("\n--->absolutePath:" + context.getFilesDir().getAbsolutePath());// /data/user/0/top.itaso.app/files
        privateDirsBuilder.append("\n--->parentPath:" + context.getFilesDir().getParent());// /data/user/0/top.itaso.app
        privateDirsBuilder.append("\n--->parentFile:" + context.getFilesDir().getParentFile());// /data/user/0/top.itaso.app
        try {
            privateDirsBuilder.append("\n--->canonicalPath:" + context.getFilesDir().getCanonicalPath());// /data/data/top.itaso.app/files
        } catch (IOException e) {
            e.printStackTrace();
        }
        privateDirsBuilder.append("\n--->freeSpace:" + context.getFilesDir().getFreeSpace() + "->" + FileUtils.formatFileSize(context.getFilesDir().getFreeSpace()));
        privateDirsBuilder.append("\n--->totalSpace:" + context.getFilesDir().getTotalSpace() + "->" + FileUtils.formatFileSize(context.getFilesDir().getTotalSpace()));

        privateDirsBuilder.append("\nFrom Content.getCacheDir:");
        //应用程序缓存文件的目录的路径。强烈鼓励应用程序将缓存空间的使用保持在满额。当该文件夹超额时，系统将自动删除该目录中的文件为其他地方提供需要空间，当不满额时则不会。不需要额外的权限来读取或在返回的路径下写入文件。
        privateDirsBuilder.append("\n--->cacheDir:" + context.getCacheDir());// /data/user/0/top.itaso.app/cache

        privateDirsBuilder.append("\nFrom Content.getObbDir:");
        //返回到应用程序特定目录的绝对路径。可能返回NULL。不需要额外权限。
        privateDirsBuilder.append("\n--->obbDir:" + context.getObbDir());// /storage/emulated/0/Android/obb/top.itaso.app

        privateDirsBuilder.append("\nFrom Content.getNoBackupFilesDir:");
        //不会自动备份到远程存储的应用程序文件的路径
        privateDirsBuilder.append("\n--->noBackupFilesDir:" + context.getNoBackupFilesDir());// /data/user/0/top.itaso.app/no_backup

        privateDirsBuilder.append("\nFrom Content.getCodeCacheDir:");
        //保存应用程序代码缓存文件的目录路径。适合在运行时存放应用产生的编译或者优化的代码。不需要额外权限
        privateDirsBuilder.append("\n--->codeCacheDir:" + context.getCodeCacheDir());// /data/user/0/top.itaso.app/code_cache

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            privateDirsBuilder.append("\nFrom Content.getDataDir:");
            //返回文件系统目录的绝对路径，所有属于该应用程序的私有文件都存储在文件系统中。应用程序不应该直接使用这个路径，而是应该在这个类上使用{getFilesDir()}、{getCacheDir()}、{getDir(String, int)}或其他存储API。
            privateDirsBuilder.append("\n--->dataDir:" + context.getDataDir());// /data/user/0/top.itaso.app
        }

        privateDirsBuilder.append("\nFrom Content.getPackageCodePath:");
        //此上下文的主Android包的完整路径。这对应用程序通常没有用处，因为它们不应该直接访问文件系统。
        privateDirsBuilder.append("\n--->packageCodePath:" + context.getPackageCodePath());// /data/app/~~OmR7auGczgizmF2OKdtyPA==/top.itaso.app-An-Wnh0tt01bL5bJpafXwA==/base.apk

        privateDirsBuilder.append("\nFrom Content.getPackageResourcePath:");
        //基本跟mContext.getPackageCodePath()相同。
        privateDirsBuilder.append("\n--->packageResourcePath:" + context.getPackageResourcePath());// /data/app/~~OmR7auGczgizmF2OKdtyPA==/top.itaso.app-An-Wnh0tt01bL5bJpafXwA==/base.apk

        privateDirsBuilder.append("\nFrom Content.getExternalFilesDir:");
        //应用程序特定目录的绝对路径，与 mContext.getFilesDir() 相似。这些文件是应用程序内部的，通常不作为媒体文件对用户展示。
        privateDirsBuilder.append("\n--->externalFilesDir:" + context.getExternalFilesDir("alog"));// /storage/emulated/0/Android/data/top.itaso.app/files/alog
        privateDirsBuilder.append("\nFrom Content.getExternalCacheDir:");
        //应用程序特定目录的绝对路径，与 mContext.getCacheDir() 相似，区别在于平台并不总是监视共享存储中可用的空间，因此可能不会自动删除这些文件。这些文件是应用程序内部的，通常不作为媒体文件对用户展示。
        privateDirsBuilder.append("\n--->externalFilesDir:" + context.getExternalCacheDir());// /storage/emulated/0/Android/data/top.itaso.app/cache

        privateDirsBuilder.append("\nFrom Environment:");
        privateDirsBuilder.append("\n--->externalStoragePublicDirectory:" + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS));// /storage/emulated/0/Download
        privateDirsBuilder.append("\n--->dataDir:" + Environment.getDataDirectory());// /data
        privateDirsBuilder.append("\n--->extStorageState:" + Environment.getExternalStorageState());// mounted
        privateDirsBuilder.append("\n--->downloadCacheDir:" + Environment.getDownloadCacheDirectory());// /data/cache
        privateDirsBuilder.append("\n--->rootDir:" + Environment.getRootDirectory());// /system
        privateDirsBuilder.append("\n--->storageDir:" + Environment.getStorageDirectory());// /storage
        privateDirsBuilder.append("\n--->extStorageDir:" + Environment.getExternalStorageDirectory());// /storage/emulated/0

        privateDirsBuilder.append("\nFrom Volumes:");
        List<UStorageVolume> volumes = getVolumes(context);
        for (UStorageVolume uStorageVolume : volumes) {
            privateDirsBuilder.append("\n--->" + uStorageVolume.getLabel() + ":" + uStorageVolume.toString());
        }
        Log.d(TAG, "getAppPrivateDir: >>>>>>" + privateDirsBuilder.toString());


        return privateDirsBuilder.toString();
    }


    /**
     * 获取挂在的存储设备，如内部存储、外部存储的 SDCard、U盘等
     * StorageVolume:存储卷、存储磁盘
     *
     * @param context
     */
//    public static List<UStorageVolume> getStorageVolumes(Context context) {
//        Log.e(TAG, "getStorageVolumes: >>>>>>>>>>>>");
//        StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
////        StorageManager storageManager = context.getSystemService(StorageManager.class);
//
//        ArrayList<UStorageVolume> uStorageVolumes = new ArrayList<>();
//        Log.d(TAG, "getStorageVolumes: >>>>>>Build.VERSION.SDK_INT:" + Build.VERSION.SDK_INT);
//
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//            try {
//                Class storageManagerClazz = Class.forName("android.os.storage.StorageManager");
//                Method getStorageVolumesMethod = storageManagerClazz.getMethod("getVolumeList");
//                List<StorageVolume> storageVolumeInfos = (List<StorageVolume>) getStorageVolumesMethod.invoke(storageManager);
//                if (storageVolumeInfos != null) {
//                    Log.d(TAG, "getStorageVolumes: >>>>>>storageVolumes.size=" + storageVolumeInfos.size());
//                    for (StorageVolume storageVolume : storageVolumeInfos) {
//                        if (null == storageVolume) {
//                            Log.e(TAG, "getStorageVolumes: >>>>>>storageVolume is Null");
//                            continue;
//                        }
//                        UStorageVolume uStorageVolume = new UStorageVolume();
//                        //是否是可移除的外部存储设备
//                        boolean isRemovable = storageVolume.isRemovable();
//                        //这个其实就是U盘的名称
//                        String label = storageVolume.getDescription(context);
//                        //设备挂载的状态，如:mounted、unmounted
//                        String status = storageVolume.getState();
////                        File dirFile = storageVolume.getDirectory();
//                        String uuid = storageVolume.getUuid();
////                        String mediaStoreVolumeName = storageVolume.getMediaStoreVolumeName();
//                        //是否是内部存储设备
//                        boolean isEmulated = storageVolume.isEmulated();
//
//                        uStorageVolume.setUuid(uuid);
//                        uStorageVolume.setLabel(label);
//                        uStorageVolume.setEmulated(isEmulated);
//                        uStorageVolume.setRemovable(isRemovable);
//                        uStorageVolume.setStatus(status);
//
//                        Class storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
//                        Method getPathMethod = storageVolumeClazz.getDeclaredMethod("getInternalPath",null);
//                        getPathMethod.setAccessible(true);
//                        //设备的路径
//                        String path = (String) getPathMethod.invoke(storageVolume);
//                        uStorageVolume.setPath(path);
//                        Log.d(TAG, "getStorageVolumes: >>>>>>uStorageVolume=" + uStorageVolume.toString());
//                        uStorageVolumes.add(uStorageVolume);
//                    }
//                }
//            } catch (ClassNotFoundException e) {
//                e.printStackTrace();
//            } catch (NoSuchMethodException e) {
//                e.printStackTrace();
//            } catch (IllegalAccessException e) {
//                e.printStackTrace();
//            } catch (InvocationTargetException e) {
//                e.printStackTrace();
//            }
//
//        }
//
//
//        return uStorageVolumes;
//    }
    public static void getUsbDevices(Context context) {
        UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
        while (deviceIterator.hasNext()) {
            UsbDevice device = deviceIterator.next();

            Log.d(TAG, "getDevice: >>>>>>DeviceName=" + device.getDeviceName() + ",ProductName=" + device.getProductName() + ",DeviceClass=" + device.getDeviceClass() + ",DeviceSubclass=" + device.getDeviceSubclass());
            for (int i = 0; i < device.getInterfaceCount(); i++) {
                UsbInterface usbInterface = device.getInterface(i);
                Log.e(TAG, "getDevice: >>>>>>" + i + ":InterfaceClass=" + usbInterface.getInterfaceClass() + ",nterfaceSubclass=" + usbInterface.getInterfaceSubclass());
            }
            Log.d(TAG, "getDevice: >>>>>>下一个");
        }

    }

    /**
     * 存储
     */
    public static class UStorageVolume {
        private String fsUuid;
        /**
         * 存储盘的盘符名称：用户可自行重命名
         */
        private String label;

        /**
         * 存储盘的名称：用户无法随意更改
         */
        private String fsLabel;

        /**
         * 存储设备的路径，如外部存储的 /storage/sda1、内置卡的 /storage/emulated
         */
        private String path;
        /**
         * 存储设备的路径，如 /mnt/media_rw/sda1、/data/media
         */
        private String internalPath;
        /**
         * 是否为可移除，可移除的即为外部存储盘
         */
        private boolean isRemovable;

        /**
         * @see UStorageVolume.flags
         */
        boolean isUsbDisk;
        /**
         * @see UStorageVolume.flags
         */
        boolean isSdDisk;

        /**
         * Android/system/vold/binder/android/os/IVold.aidl
         * 设备挂载的状态，如:mounted、unmounted
         * STATE_UNMOUNTED = IVold.VOLUME_STATE_UNMOUNTED;  0
         * STATE_CHECKING = IVold.VOLUME_STATE_CHECKING;    1
         * STATE_MOUNTED = IVold.VOLUME_STATE_MOUNTED;  2
         * STATE_MOUNTED_READ_ONLY = IVold.VOLUME_STATE_MOUNTED_READ_ONLY;  3
         * STATE_FORMATTING = IVold.VOLUME_STATE_FORMATTING;    4
         * STATE_EJECTING = IVold.VOLUME_STATE_EJECTING;    5
         * STATE_UNMOUNTABLE = IVold.VOLUME_STATE_UNMOUNTABLE;  6
         * STATE_REMOVED = IVold.VOLUME_STATE_REMOVED;  7
         * STATE_BAD_REMOVAL = IVold.VOLUME_STATE_BAD_REMOVAL;  8
         */
        private int status;


        /**
         * Android/system/vold/binder/android/os/IVold.aidl
         * <p>
         * TYPE_PUBLIC = IVold.VOLUME_TYPE_PUBLIC;  0
         * TYPE_PRIVATE = IVold.VOLUME_TYPE_PRIVATE;    1
         * TYPE_EMULATED = IVold.VOLUME_TYPE_EMULATED;  2
         * TYPE_ASEC = IVold.VOLUME_TYPE_ASEC;  3
         * TYPE_OBB = IVold.VOLUME_TYPE_OBB;    4
         * TYPE_STUB = IVold.VOLUME_TYPE_STUB;  5
         */
        private int type;

        /**
         * FLAG_ADOPTABLE = 1 << 0
         * FLAG_DEFAULT_PRIMARY = 1 << 1
         * FLAG_SD = 1 << 2
         * FLAG_USB = 1 << 3
         * FLAG_STUB_VISIBLE = 1 << 6
         */
        private int flags;
        /**
         * 是否为 模拟卷 是否是内部存储设备
         */
        private boolean isEmulated;

        public String getFsUuid() {
            return fsUuid;
        }

        public void setFsUuid(String fsUuid) {
            this.fsUuid = fsUuid;
        }

        public String getLabel() {
            return label;
        }

        public void setLabel(String label) {
            this.label = label;
        }

        public String getFsLabel() {
            return fsLabel;
        }

        public void setFsLabel(String fsLabel) {
            this.fsLabel = fsLabel;
        }

        public String getPath() {
            return path;
        }

        public void setPath(String path) {
            this.path = path;
        }

        public String getInternalPath() {
            return internalPath;
        }

        public void setInternalPath(String internalPath) {
            this.internalPath = internalPath;
        }

        public boolean isRemovable() {
            return isRemovable;
        }

        public void setRemovable(boolean removable) {
            isRemovable = removable;
        }

        public boolean isUsbDisk() {
            return isUsbDisk;
        }

        public void setUsbDisk(boolean usbDisk) {
            isUsbDisk = usbDisk;
        }

        public boolean isSdDisk() {
            return isSdDisk;
        }

        public void setSdDisk(boolean sdDisk) {
            isSdDisk = sdDisk;
        }

        public int getStatus() {
            return status;
        }

        public void setStatus(int status) {
            this.status = status;
        }

        public void setStatus(String status) {
            this.status = convertToState(status);
        }

        public int getType() {
            return type;
        }

        public void setType(int type) {
            this.type = type;
        }

        public int getFlags() {
            return flags;
        }

        public void setFlags(int flags) {
            this.flags = flags;
        }

        public boolean isEmulated() {
            return isEmulated;
        }

        public void setEmulated(boolean emulated) {
            isEmulated = emulated;
        }

        private int convertToState(String state) {
            int convertResult = -1;
            switch (state.toLowerCase()) {
                case "unmounted":
                    convertResult = 0;
                    break;
                case "checking":
                    convertResult = 1;
                    break;
                case "nofs":
                    break;
                case "mounted":
                    convertResult = 2;
                    break;
                case "mounted_ro":
                    convertResult = 3;
                    break;
                case "shared":
                    convertResult = 4;
                    break;
                case "ejecting":
                    convertResult = 5;
                    break;
                case "unmountable":
                    convertResult = 6;
                case "removed":
                    convertResult = 7;
                    break;
                case "bad_removal":
                    convertResult = 8;
                    break;
                default:
                    break;
            }
            return convertResult;
        }

        @Override
        public String toString() {
//            UStorageVolume{uuid='', label='', fsLabel='内部共享存储空间', path='/data', internalPath='', isRemovable=false, isUsbDisk=false, isSdDisk=false, status=2, type=1, flags=0, isEmulated=true}
//            UStorageVolume{uuid='', label='', fsLabel='内部共享存储空间', path='/storage/emulated', internalPath='/data/media', isRemovable=false, isUsbDisk=false, isSdDisk=false, status=2, type=2, flags=0, isEmulated=true}
//            UStorageVolume{uuid='AE11-DE79', label='General U 盘', fsLabel='ASO', path='/storage/sda1', internalPath='/mnt/media_rw/sda1', isRemovable=true, isUsbDisk=true, isSdDisk=false, status=2, type=0, flags=9, isEmulated=false}
            return "UStorageVolume{" +
                    "uuid='" + fsUuid + '\'' +
                    ", label='" + label + '\'' +
                    ", fsLabel='" + fsLabel + '\'' +
                    ", path='" + path + '\'' +
                    ", internalPath='" + internalPath + '\'' +
                    ", isRemovable=" + isRemovable +
                    ", isUsbDisk=" + isUsbDisk +
                    ", isSdDisk=" + isSdDisk +
                    ", status=" + status +
                    ", type=" + type +
                    ", flags=" + flags +
                    ", isEmulated=" + isEmulated +
                    '}';
        }
    }
}
